<?php
declare(strict_types=1);
/**
 * Created by project.
 * User: huanzipap
 * Date: 2023/5/10
 * Time: 11:25
 */
namespace App\Controller\User;

use App\Controller\AppBaseController;
use App\Model\Act;
use App\Model\ActClockJoinComment;
use App\Model\ActClockJoinZan;
use App\Model\ActJoin;
use App\Model\ActRead;
use App\Model\ActClockPoint;
use App\Model\ActClockJoin;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\HttpServer\Annotation\Middleware;
use App\Middleware\WxApiAuth;
use Hyperf\DbConnection\Db;

#[Controller(prefix: 'user')]
#[Middleware(WxApiAuth::class)]
class ActClockController extends AppBaseController
{

    /**
     * 活动打卡点-列表
     * @param int $act_id
     * @return object
     * @throws \RedisException
     */
    #[RequestMapping(path: 'actClockPointList/{act_id}',methods: 'post,get')]
    public function actClockPointList(int $act_id): object
    {
        //redis锁名称，写在外面用户异常解锁
        try{
            //验证用户信息
            $checkInfo = $this->checkUser();
            if($checkInfo['status']==40002) return $this->reMsg->re(10002,$checkInfo['message']);
            $_user = $checkInfo['data'];

            //活动信息
            $info = Act::where('id',$act_id)->first();
            if(empty($info)) return $this->reMsg->re(10008);
            if($info->type != 4) return $this->reMsg->re(0,'活动类型有误');

            //获取本次活动的所有打卡点
            $list = ActClockPoint::where('act_id',$act_id)->get();

            //获取已经打开的总数
            $pointCount = ActClockJoin::where('act_id',$act_id)->count();
            $backData = [
                'list'=>$list,
                'point_count'=>$pointCount
            ];
            return $this->reMsg->re(1,'success',$backData);
        }catch (\Exception $exception){
            return $this->diyError->errorJson($exception);
        }
    }


    /**
     * 活动打卡点-打卡记录
     * @param int $point_id
     * @return object
     * @throws \RedisException
     */
    #[RequestMapping(path: 'actClockJoinList/{point_id}',methods: 'post,get')]
    public function actClockJoinList(int $point_id): object
    {
        try{
            //验证用户信息
            $checkInfo = $this->checkUser();
            if($checkInfo['status']==40002) return $this->reMsg->re(10002,$checkInfo['message']);
            $_user = $checkInfo['data'];

            //打卡点信息
            $info = ActClockPoint::where('id',$point_id)->first();
            if(empty($info)) return $this->reMsg->re(10008);

            //查看自己是否打卡
            $clockMeWhere['point_id'] = $point_id;
            $clockMeWhere['uid'] = $_user->id;

            $clockMe = 0;
            $clockMeInfo = ActClockJoin::where($clockMeWhere)->first();
            if($clockMeInfo){
                $clockMe = 1;
            }

            //获取列表
            $page = $this->request->input('page', 1);
            $limit = $this->request->input('limit', 20);
            $offset = ($page - 1) * $limit;

            //获取本次活动的打卡点打卡记录
            $where['status'] = 1;
            $where['point_id'] = $point_id;
            $list = ActClockJoin::with(['user'=>function ($query) {
                    $query->selectRaw('id,avatar,auth_name')->get();
                 },'zan'=>function($query){
                    $query->with(['user'=>function ($query) {
                        $query->selectRaw('id,avatar,auth_name')->where('status',1)->get();
                    }])->selectRaw('id,join_id,uid,status')->where('status',1)->get();
                },'comment'=>function($query){
                    $query->with(['user'=>function ($query) {
                        $query->selectRaw('id,avatar,auth_name')->where('status',1)->get();
                    }])->selectRaw('id,join_id,uid,message,status')->get();
                }])
                ->where($where)
                ->selectRaw('id,act_id,point_id,uid,title,media_list,created_at')
                ->orderByDesc('id')
                ->offset($offset)
                ->limit($limit)
                ->get();

            //获取打卡点总的打卡次数
            $clockCount = ActClockJoin::where($where)->count();

            $backData = [
                'clock_count'=>$clockCount,
                'clock_me'=>$clockMe,
                'list'=>$list
            ];
            return $this->reMsg->re(1,'success',$backData);
        }catch (\Exception $exception){
            return $this->diyError->errorJson($exception);
        }
    }



    /**
     * 打卡签到
     * @param int $point_id
     * @return object
     * @throws \RedisException
     */
    #[RequestMapping(path: 'actClockJoin/{point_id}',methods: 'post,get')]
    public function actClockJoin(int $point_id): object
    {
        try{
            //验证用户信息
            $checkInfo = $this->checkUser();
            if($checkInfo['status']==40002) return $this->reMsg->re(10002,$checkInfo['message']);
            $_user = $checkInfo['data'];

            //查看打卡点是否存在
            $pointInfo = ActClockPoint::where('id',$point_id)->first();
            if(empty($pointInfo)) return $this->reMsg->re(10008,'打卡点位失效');
            $info = Act::where('id',$pointInfo->act_id)->first();
            if(empty($info)) return $this->reMsg->re(10008);
            //判断类型
            if($info->type != 4) return $this->reMsg->re(0,'活动类型有误');
            //判断开始时间
            if($info->start_time && time()<strtotime($info->start_time)) return $this->reMsg->re(0,'活动未开始');
            //判断结束时间
            if($info->end_time && time()>strtotime($info->end_time)) return $this->reMsg->re(0,'活动已结束');
            //判断参与人数
            if($info->max_limit>0 && $info->join_count>=$info->max_limit) return $this->reMsg->re(0,'参与人数超过限制');

            //查看用户该站点是否已经打开
            $searchWhere['point_id'] = $point_id;
            $searchWhere['uid'] = $_user->id;
            $clockMe = ActClockJoin::where($searchWhere)->first();
            if($clockMe) return $this->reMsg->re(0,'本站点已打卡');

            $title = $this->request->input('title', '打卡测试');
            if(empty($title)) return $this->reMsg->re(0,'请输入打卡标题');
            $media_list = $this->request->input('media_list', null);
            if(empty($media_list) || !is_array($media_list)) $media_list = [];

            $insertData['party_id'] = $info->party_id;
            $insertData['act_id'] = $info->id;
            $insertData['uid'] = $_user->id;
            $insertData['point_id'] = $point_id;
            $insertData['title'] = $title;
            if(is_array($media_list)){
                $insertData['media_list'] = $media_list;
            }

            Db::beginTransaction();

            $insertRet = ActClockJoin::create($insertData);
            if($insertRet){
                //需要往我们混动参加记录里面加一条 参与记录  不可重复
                $actWhere['act_id'] = $info->id;
                $actWhere['uid'] = $_user->id;
                $actJoinLog = ActJoin::where($actWhere)->first();
                if(empty($actJoinLog)){
                    $actWhere['party_id'] = $info->party_id;
                    $actWhere['title'] = $info->title;
                    $actWhere['photo'] = $info->photo;
                    ActJoin::create($actWhere);

                    Act::where('id',$info->id)->increment('join_count',1); //活动参与人数加1
                    //加积分
                    $addType = 0;
//                    if($info->type==2) $addType = 6; //报名
                    if($info->type==4) $addType = 8; //签到打卡
                    $params = [
                        'type'=> $addType, //积分类型 type 1:学习 2:评论 4:支部活动点赞 5:答题 6:报名 7:抽奖 8:签到打卡 9:问卷 10:支部信息更新
                        'action' => 1, //action 1:加积分 2:减积分
                        'uid' => $_user->id,  //用户id
                        'party_id' => $_user->party_id  //支部id
                    ];
                    $this->makeIntegralLog($params);
                }
                Db::commit();
                return $this->reMsg->re(1,'success');
            }else{
                Db::rollBack();
                return $this->reMsg->re(0,'fail');
            }
        }catch (\Exception $exception){
            Db::rollBack();
            return $this->diyError->errorJson($exception);
        }
    }



    /**
     * 活动打卡点-打卡记录|点赞
     * @param int $join_id
     * @return object
     * @throws \RedisException
     */
    #[RequestMapping(path: 'actClockJoinZan/{join_id}',methods: 'post,get')]
    public function actClockJoinZan(int $join_id): object
    {
        try{
            //验证用户信息
            $checkInfo = $this->checkUser();
            if($checkInfo['status']==40002) return $this->reMsg->re(10002,$checkInfo['message']);
            $_user = $checkInfo['data'];

            //打卡点信息
            $info = ActClockJoin::where('id',$join_id)->first();
            if(empty($info)) return $this->reMsg->re(10008);

            $insertData['join_id'] = $join_id;
            $insertData['uid'] = $_user->id;

            //查询是否已经点赞
            $zanInfo = ActClockJoinZan::where($insertData)->first();
            if($zanInfo){
                if($zanInfo->status==1){
                    $zanStatus = 0;
                }else{
                    $zanStatus = 1;
                }
                $zanInfo->status = $zanStatus;
                $zanInfo->save();
            }else{
                $insertData['party_id'] = $info->party_id;
                $insertData['act_id'] = $info->id;
                $insertData['point_id'] = $info->point_id;
                ActClockJoinZan::create($insertData);
            }
            return $this->reMsg->re(1,'success');
        }catch (\Exception $exception){
            return $this->diyError->errorJson($exception);
        }
    }


    /**
     * 活动打卡点-打卡记录|评论
     * @param int $join_id
     * @return object
     * @throws \RedisException
     */
    #[RequestMapping(path: 'actClockJoinComment/{join_id}',methods: 'post,get')]
    public function actClockJoinComment(int $join_id): object
    {
        try{
            //验证用户信息
            $checkInfo = $this->checkUser();
            if($checkInfo['status']==40002) return $this->reMsg->re(10002,$checkInfo['message']);
            $_user = $checkInfo['data'];

            //打卡点信息
            $info = ActClockJoin::where('id',$join_id)->first();
            if(empty($info)) return $this->reMsg->re(10008);

            $message = $this->request->input('message', '');
            if(empty($message)) return $this->reMsg->re(0,'评论内容不为空');

            $insertData['party_id'] = $info->party_id;
            $insertData['act_id'] = $info->id;
            $insertData['point_id'] = $info->point_id;
            $insertData['join_id'] = $join_id;
            $insertData['uid'] = $_user->id;
            $insertData['message'] = $message;
            ActClockJoinComment::create($insertData);
            return $this->reMsg->re(1,'success');
        }catch (\Exception $exception){
            return $this->diyError->errorJson($exception);
        }
    }



    /**
     * 活动打卡点-打卡排行
     * @param int $act_id
     * @return object
     * @throws \RedisException
     */
    #[RequestMapping(path: 'actClockRankList/{act_id}',methods: 'post,get')]
    public function actClockRankList(int $act_id): object
    {
        try{
            //验证用户信息
            $checkInfo = $this->checkUser();
            if($checkInfo['status']==40002) return $this->reMsg->re(10002,$checkInfo['message']);
            $_user = $checkInfo['data'];

            //打卡点信息
            $info = Act::where('id',$act_id)->first();
            if(empty($info)) return $this->reMsg->re(10008);

            //获取列表
            $page = $this->request->input('page', 1);
            $limit = $this->request->input('limit', 20);
            $offset = ($page - 1) * $limit;

            $list = ActClockJoin::with(['user'=>function ($query) {
                    $query->selectRaw('id,avatar,auth_name')->get();
                }])->where('act_id',$info->id)
                ->selectRaw('id,uid,count(id) as clock_count,created_at')
                ->groupBy('uid')
                ->orderByDesc('clock_count')
                ->orderBy('created_at')
                ->offset($offset)
                ->limit($limit)
                ->get();

            $backData = [
                'list'=>$list
            ];
            return $this->reMsg->re(1,'success',$backData);
        }catch (\Exception $exception){
            return $this->diyError->errorJson($exception);
        }
    }

}